from usuario import Usuario, db_session
from proyecto import Proyecto
from comite import Comite
from rol import Rol
from fase import Fase
from sqlalchemy import exc
from flask import flash
session = db_session()

class UsuarioManager(object):
    """Clase encargada del manejo de usuarios"""
    def __init__(self):
        pass
    def __repr__(self):
        return '<Usuario Manager>'
    
    def guardarUsuario(self, usuario):
        """
        Metodo encargado de almacenar un usuario en la base de datos
        @param usuario: Objeto usuario que se desea guardar.
        """
        session.add(usuario)
        try:
            session.commit()
        except exc.IntegrityError as ex:
            session.rollback()
            
            return flash("El usuario ya existe", "error")
        else:
            return flash("Usuario registrado exitosamente")
        
    def guardarUsuarioRol(self, usuario):
        """
        Metodo encargado de almacenar los roles de un usuario en la base de datos
        @param usuario: objeto usuario que se desea modificar.
        """
        session.add(usuario)
        try:
            session.commit()
        except exc.IntegrityError as ex:
            session.rollback()
            return flash("El rol ya existe", "error")
        else:
            return flash("Rol asignado exitosamente")
        
    def eliminarUsuarioRol(self, usuario):
        """
        Metodo encargado de eliminar un rol de un usuario de la base de datos
        @param usuario: objeto usuario que se desea modificar.
        """
        session.add(usuario)
        try:
            session.commit()
        except exc.IntegrityError as ex:
            session.rollback()
            return flash("El rol ya fue desasignado", "error")
        else:
            return flash("Rol desasignado exitosamente")
#        session.close()
        
    def eliminarUsuario(self, idusuario):
        """
        Metodo encargado de almacenar los roles de un usuario en la base de datos
        @param idusuario: id del usuario que se desea eliminar.
        """
#        session = db_session()
        usuario = session.query(Usuario).filter(Usuario.idusuario==idusuario).first()
        session.delete(usuario)
        session.commit()
        
    def getUsuario(self, idusuario):
        """
        Metodo encargado de retornar un usuario de la base de datos
        @param idusuario: id del usuario que se desea obtener.
        """
        usuario = session.query(Usuario).filter(Usuario.idusuario==idusuario).first()
        return usuario 
    
    def getUsuarios(self):
        """Metodo encargado de retornar todos los usuarios de la base de datos"""
        usuarios = session.query(Usuario).order_by(Usuario.nombre).all()
        users = self.getUsuarioPorUser("admin")
        if users in usuarios:
            usuarios.remove(users)
        
        return usuarios
    
    def getUsuarioFiltradoPorUser(self, user):
        """
        Metodo encargado de retornar un usuario dado su nombre
        @param user: nombre del usuario que se desea obtener.
        """
        if user == "":
            user = "%"
        else:
            user = "%"+user+"%"
        usuario = session.query(Usuario).filter(Usuario.usuario.like(user)).order_by(Usuario.nombre).first()
        return usuario
    
    def getUsuarioPorUser(self, user):
        """
        Metodo encargado de retornar un usuario dado su nombre
        @param user: nombre del usuario que se desea obtener.
        """
        usuario = session.query(Usuario).filter(Usuario.usuario==user).first()
        return usuario
    
    def getRolesDelUsuario(self, user):
        """
        Metodo encargado de retornar los roles de un usuario
        @param user: nombre del usuario cuyos roles se desean obtener.
        """
        user = session.query(Usuario).filter(Usuario.usuario==user)
        return user.roles
    
    def getUsuariosPaginado(self, user, desde, hasta):
        """
        Metodo encargado de retornar un usuario dado su nombre
        @param user: nombre del usuario que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if user == "":
            user = "%"
        else:
            user = "%"+user+"%"

        if desde != None and hasta != None:
            usuarios = session.query(Usuario).filter(Usuario.usuario.like(user)).filter(Usuario.usuario!='admin').order_by(Usuario.nombre)[desde:hasta]
            users = self.getUsuarioPorUser("admin")

            return usuarios  
        else: 
            total = session.query(Usuario).filter(Usuario.usuario.like(user)).filter(Usuario.usuario!='admin').order_by(Usuario.nombre).count()
            return total
        
    def getUsuariosPorProyectoPaginado(self, idproyecto, nombre, desde, hasta):
        """
        Metodo encargado de retornar un usuario dado su nombre
        @param idproyecto: id del proyecto cuyos usuarios se desean obtener.
        @param nombre: nombre del usuario que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"

        if desde != None and hasta != None:
            usuarios =  session.query(Usuario).join((Rol, Usuario.roles)).join(Fase).join(Proyecto).filter(Proyecto.idproyecto==idproyecto).\
                                        filter(Usuario.nombre.like(nombre)).distinct(Usuario.idusuario)[desde:hasta]
            
            return usuarios
        else:
            total = session.query(Usuario).join((Rol, Usuario.roles)).join(Fase).join(Proyecto).filter(Proyecto.idproyecto==idproyecto).\
                                        filter(Usuario.nombre.like(nombre)).distinct().count()
            return total
        
    def getUsuariosPorComite(self, idcomite):
        """
        Metodo encargado de retornar los usuarios integrantes de un comite
        @param idcomite: id del comite cuyos integrantes se desean obtener.
        """
        users = session.query(Usuario).join((Comite, Usuario.comites)).join(Proyecto).filter(Comite.idcomite==idcomite).order_by(Usuario.nombre).all()
        return users
